package net.cyue.util;

import java.util.Locale;

public class IdentifierStringConverter {
    // 私有构造函数，防止实例化工具类
    private IdentifierStringConverter() {
        throw new AssertionError("工具类不允许实例化");
    }

    /**
     * 将下划线风格转换为驼峰风格
     * 处理连续下划线、首尾下划线、空白字符等边界情况
     */
    public static String snake2CamelCase(String underScore) {
        // 处理null和空白字符串
        if (isBlank(underScore)) {
            return underScore;
        }

        // 去除首尾空白和下划线
        String trimmed = underScore.trim().replaceAll("^_+", "").replaceAll("_+$", "");
        if (trimmed.isEmpty()) {
            return "";
        }

        StringBuilder result = new StringBuilder();
        boolean nextUpperCase = false;

        for (int i = 0; i < trimmed.length(); i++) {
            char currentChar = trimmed.charAt(i);

            // 处理连续下划线
            if (currentChar == '_') {
                nextUpperCase = true;
            } else {
                if (nextUpperCase) {
                    // 转换为大写，并重置标志
                    result.append(Character.toUpperCase(currentChar));
                    nextUpperCase = false;
                } else {
                    // 保持原字符（通常是小写）
                    result.append(currentChar);
                }
            }
        }

        return result.toString();
    }

    /**
     * 将驼峰风格转换为下划线风格
     * 支持处理全大写字符串、包含数字的字符串
     */
    public static String camelCase2Snake(String camelCase) {
        if (isBlank(camelCase)) {
            return camelCase;
        }

        String trimmed = camelCase.trim();
        if (trimmed.isEmpty()) {
            return "";
        }

        // 处理全大写的情况（如CONSTANT_VALUE）
        if (trimmed.equals(trimmed.toUpperCase(Locale.ROOT))) {
            return trimmed.toLowerCase(Locale.ROOT);
        }

        StringBuilder result = new StringBuilder();
        // 第一个字符转为小写
        result.append(Character.toLowerCase(trimmed.charAt(0)));

        for (int i = 1; i < trimmed.length(); i++) {
            char currentChar = trimmed.charAt(i);

            // 大写字母前添加下划线并转为小写
            if (Character.isUpperCase(currentChar)) {
                result.append('_');
                result.append(Character.toLowerCase(currentChar));
            }
            // 数字前如果不是分隔符，添加下划线
            else if (Character.isDigit(currentChar) && i > 0 &&
                    !Character.isDigit(trimmed.charAt(i-1)) &&
                    !Character.isUpperCase(trimmed.charAt(i-1))) {
                result.append('_');
                result.append(currentChar);
            }
            // 其他字符直接添加
            else {
                result.append(currentChar);
            }
        }

        return result.toString();
    }

    /**
     * 将连字符风格转换为驼峰风格
     */
    public static String hyphen2CamelCase(String hyphen) {
        if (isBlank(hyphen)) {
            return hyphen;
        }

        // 去除首尾空白和连字符
        String trimmed = hyphen.trim().replaceAll("^-+", "").replaceAll("-+$", "");
        if (trimmed.isEmpty()) {
            return "";
        }

        StringBuilder result = new StringBuilder();
        boolean nextUpperCase = false;

        for (int i = 0; i < trimmed.length(); i++) {
            char currentChar = trimmed.charAt(i);

            if (currentChar == '-') {
                nextUpperCase = true;
            } else {
                if (nextUpperCase) {
                    result.append(Character.toUpperCase(currentChar));
                    nextUpperCase = false;
                } else {
                    result.append(currentChar);
                }
            }
        }

        return result.toString();
    }

    /**
     * 将驼峰风格转换为连字符风格
     */
    public static String camelCase2Hyphen(String camelCase) {
        if (isBlank(camelCase)) {
            return camelCase;
        }

        String trimmed = camelCase.trim();
        if (trimmed.isEmpty()) {
            return "";
        }

        // 处理全大写的情况
        if (trimmed.equals(trimmed.toUpperCase(Locale.ROOT))) {
            return trimmed.toLowerCase(Locale.ROOT);
        }

        StringBuilder result = new StringBuilder();
        result.append(Character.toLowerCase(trimmed.charAt(0)));

        for (int i = 1; i < trimmed.length(); i++) {
            char currentChar = trimmed.charAt(i);

            if (Character.isUpperCase(currentChar)) {
                result.append('-');
                result.append(Character.toLowerCase(currentChar));
            } else if (Character.isDigit(currentChar) && i > 0 &&
                    !Character.isDigit(trimmed.charAt(i-1)) &&
                    !Character.isUpperCase(trimmed.charAt(i-1))) {
                result.append('-');
                result.append(currentChar);
            } else {
                result.append(currentChar);
            }
        }

        return result.toString();
    }

    /**
     * 下划线与连字符直接转换
     */
    public static String snake2Hyphen(String underScore) {
        if (isBlank(underScore)) {
            return underScore;
        }
        return underScore.replace('_', '-');
    }

    public static String hyphen2Snake(String hyphen) {
        if (isBlank(hyphen)) {
            return hyphen;
        }
        return hyphen.replace('-', '_');
    }

    /**
     * 检查字符串是否为null、空或仅包含空白字符
     */
    private static boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }

    // 测试方法 - 包含各种边界情况测试
    public static void main(String[] args) {
        // 测试下划线转驼峰
        testUnderScoreToCamelCase();

        // 测试驼峰转下划线
        testCamelCaseToUnderScore();

        // 测试连字符相关转换
        testHyphenConversions();
    }

    private static void testUnderScoreToCamelCase() {
        System.out.println("=== 下划线转驼峰测试 ===");
        testCase(snake2CamelCase(null), null);
        testCase(snake2CamelCase(""), "");
        testCase(snake2CamelCase("   "), "   ");
        testCase(snake2CamelCase("_hello"), "hello");
        testCase(snake2CamelCase("hello_"), "hello");
        testCase(snake2CamelCase("hello__world"), "helloWorld");
        testCase(snake2CamelCase("  hello_world  "), "helloWorld");
        testCase(snake2CamelCase("HELLO_WORLD"), "HELLOWORLD");
        System.out.println();
    }

    private static void testCamelCaseToUnderScore() {
        System.out.println("=== 驼峰转下划线测试 ===");
        testCase(camelCase2Snake(null), null);
        testCase(camelCase2Snake(""), "");
        testCase(camelCase2Snake("   "), "   ");
        testCase(camelCase2Snake("HelloWorld"), "hello_world");
        testCase(camelCase2Snake("helloWorld123"), "hello_world_123");
        testCase(camelCase2Snake("HELLO_WORLD"), "hello_world");
        testCase(camelCase2Snake("CONSTANT_VALUE"), "constant_value");
        System.out.println();
    }

    private static void testHyphenConversions() {
        System.out.println("=== 连字符转换测试 ===");
        testCase(hyphen2CamelCase("hello-world"), "helloWorld");
        testCase(hyphen2CamelCase("--hello--world--"), "helloWorld");
        testCase(camelCase2Hyphen("helloWorld123"), "hello-world-123");
        testCase(snake2Hyphen("hello_world"), "hello-world");
        testCase(hyphen2Snake("hello-world"), "hello_world");
    }

    private static void testCase(String actual, String expected) {
        boolean success = (actual == null && expected == null) ||
                (actual != null && actual.equals(expected));
        System.out.printf("实际: '%s', 预期: '%s' - %s%n",
                actual, expected, success ? "成功" : "失败");
    }
}
